// Copyright (c) 2010, Anthony Cassidy
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without modification, are 
// permitted provided that the following conditions are met:
// 
//     * Redistributions of source code must retain the above copyright notice, this list 
//         of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice, this 
//         list of conditions and the following disclaimer in the documentation and/or 
//         other materials provided with the distribution.
//     * Neither the name of the AntsAdventureGameCreator nor the names of its contributors 
//         may be used to endorse or promote products derived from this software without 
//         specific prior written permission.
// 
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
// THE POSSIBILITY OF SUCH DAMAGE.
#include "XStdafx.h"
#include "XVerbs.h"
#include "XDialogForLayout.h"
#include "XVerb.h"

#include "XDiagnostics.h"


XVerbs::XVerbs()
:m_receiver(this)
,m_verbAsNumberFontSize(-1)
,m_itemOfHighlightedVerb(-1)
,m_isVisible(true)
{

}


XVerbs::~XVerbs()
{
    XDiagnostics::Delete("XVerbs");
    for(int i=0;i<m_list.size();i++)
    {
        delete m_list[i];
    }
}

void XVerbs::DrawBackground(QPainter& painter)
{
    QBrush blackBrush(Qt::black);
    painter.fillRect(m_rect, blackBrush);
}
void XVerbs::DrawVerbIfVisible(int i, QPainter& displayPainter, QPainter& zbufferPainter, QRgb zbufferColor, bool forceRolloverOff)
{
    if(m_isVisible)
    {
        // have minimised the 
        if(i == m_itemOfHighlightedVerb && !forceRolloverOff)
        {
            displayPainter.drawImage(0,0,m_rolloverImages[i]);	
        }
        else
        {
            displayPainter.drawImage(0,0,m_images[i]);
        }

        // just draw a full rect on the zbuffer in the given color
        zbufferPainter.fillRect( m_rects[i],QBrush(zbufferColor));
    }
}

bool XVerbs::IsMouseOverVerb(int i, const QPoint& pos)
{
    return m_rects[i].contains(pos);
}

void XVerbs::SetFontSize(int verbFontSize)
{
    m_verbAsNumberFontSize = verbFontSize;
    UpdateRects();
}


void XVerbs::SetFont(QFont font)
{
    m_font = font;
    UpdateRects();
}

void XVerbs::SetHighlightedVerb(int indexOfHighlightedVerb)
{
    m_itemOfHighlightedVerb = indexOfHighlightedVerb;
}

void WipeCanvas(QImage& image)
{
    QImage black(image.width(),image.height(), QImage::Format_Mono);
    black.fill(0);
    image.setAlphaChannel(black);
}

void XVerbs::UpdateRects()
{
    // reconstruct list of verbs
    QVector<QString> listOfVerbs = this->GetVerbStringList();
    QVector<QString> verbFormats;
    QVector<QString> ids;
    for( int i=0;i<m_list.size();i++)
    {
        QString displayName = m_list[i]->DisplayName();
        verbFormats.push_back(displayName);	
        ids.push_back(QString("%1").arg(i+1));
    }

    if(listOfVerbs.size())
    {
        XDialogForLayout dialog(listOfVerbs, m_rect.height(), m_font);
        dialog.PopulateRectList();

        QVector<QRect> rects = dialog.GetListOfRects();

        //double fontSizeCL = (m_commandLineGuiFontSize != -1)? m_commandLineGuiFontSize : dialog.GetRecommendedFontSizeInPoints();
        double fontSizeVerbs = (m_verbAsNumberFontSize >1)? m_verbAsNumberFontSize : dialog.GetRecommendedFontSizeInPoints();

        // clear old images
        m_images.clear();
        m_rolloverImages.clear();
        m_rects.clear();

        // create images
        {
            // make background black
            QBrush blackBrush(Qt::black);

            int heightWhereVerbsStart = m_rect.y();

            QFont font(m_font);
            font.setPointSize((int)fontSizeVerbs);
            font.setFixedPitch(true);

            // two passes - one for rollover one for not
            for(int j=0;j<2;j++)
            {
                for( int i=0;i< listOfVerbs.size(); i++)
                {
                    QString XVerb = listOfVerbs[i];
                    QRect rect = rects[i];
                    rect.translate(0,heightWhereVerbsStart);
                    m_rects.push_back(rect);

                    // initialize image 
                    QImage image(m_rect.right(), m_rect.bottom(), QImage::Format_ARGB32_Premultiplied);
                    //image.alphaChannel().fill(0);

                    WipeCanvas(image);

                    //initialize painter
                    QPainter painter;
                    bool isOk = painter.begin(&image);
                    if(isOk)
                    {
                        painter.setFont(font);

                        // draw black bg
                        painter.fillRect(rect, blackBrush);

                        // draw text shadow
                        QRect rectOffsetOnePixel(rect.topLeft() + QPoint(1,1), rect.bottomRight() + QPoint(1,1));
                        painter.setPen(Qt::darkMagenta);
                        painter.drawText(rectOffsetOnePixel, Qt::AlignCenter|Qt::TextSingleLine , XVerb);

                        if(j==0)
                        {
                            // if normal mode, draw text in blue.
                            painter.setPen(Qt::blue);
                            painter.drawText(rect, Qt::AlignCenter|Qt::TextSingleLine , XVerb);
                            m_images.push_back(image);
                        }
                        else if (j==1)
                        {
                            // if rollover, draw text in yellow
                            painter.setPen(Qt::yellow);
                            painter.drawText(rect, Qt::AlignCenter|Qt::TextSingleLine , XVerb);
                            m_rolloverImages.push_back(image);
                        }
                        bool isOk2 = painter.end();
                        ASSERT(isOk2 && "painter failed in XVerbsGui");
                        isOk2 = isOk2;
                    }
                }
            }
        }
    }
}

void XVerbs::SetVisible(bool isVisible)
{
    m_isVisible = isVisible;
}


void XVerbs::ClearImageList()
{
    m_images.clear();
    m_rolloverImages.clear();
}

QVector<QString> XVerbs::GetVerbStringList()
{
    QVector<QString> toReturn;
    for(int i=0;i<m_list.size();i++)
    {
        QString displayName = m_list[i]->DisplayName();
        displayName.replace("AAA","");// do this first just incase in some language its first.
        displayName = displayName.trimmed();// remove whitespace, or token(0) may be a space
        QStringList tokens = displayName.split(" ");//....now split
        QString toDisplay = tokens.at(0);
        toDisplay = toDisplay.trimmed(); //just incase any non-space whitespace
        toReturn.push_back( toDisplay );
    }
    return toReturn;
}



void XVerbs::Clear()
{
    m_list.clear();
}

void XVerbs::AddNew(QString keyword, QString displayName)
{
    QPointer<XVerb> xverb = new XVerb(*this);// deleted in destructor
    xverb->SetDisplayName(displayName);
    xverb->SetKeyword(keyword);
    Add(xverb);
}

void XVerbs::Remove(QString keyword)
{
    QString lowerCase = keyword.toLower();
    int i = IndexOf(lowerCase);
    if(i!=-1)
    {
        m_list.remove(i);
        UpdateRects();
    }
}

void XVerbs::Add(QPointer<XVerb>& XVerb)
{
    m_list.push_back(XVerb);
}

int XVerbs::Count() const 
{ 
    return m_list.size();
}

QPointer<XVerb>& XVerbs::At(int i)
{ 
    return m_list[i];
}

const QPointer<XVerb>& XVerbs::ConstItem(int i) const
{ 
    return m_list[i];
}

QPointer<XVerb>& XVerbs::At(QString string)
{ 
    return m_list[IndexOf(string)];
}

int XVerbs::IndexOf(QString string) const
{ 
    int iFound = -1;
    for(int i=0;i<m_list.size();i++)
    {
        QString toTest = m_list[i]->Keyword().toLower();
        if(toTest == string)
        {
            iFound = i;
        }
    }
    return iFound;
}

void XVerbs::SetRect(QRect rect)
{ 
    m_rect = rect;
    UpdateRects();
}

// verb collection
bool XVerbs::IsVisible() const
{ 
    return m_isVisible;
}

XReceiver* XVerbs::Receiver() const 
{ 
    return m_receiver;
}
